package com.harbintransport.backend.controller;

import com.harbintransport.backend.model.HourlyTrafficTrend;
import com.harbintransport.backend.model.StationPassengerRanking;
import com.harbintransport.backend.model.DataProcessingException;
import com.harbintransport.backend.model.RouteStationFunnel;
import com.harbintransport.backend.model.RouteMobility;
import com.harbintransport.backend.model.StationCrowdRanking;
import com.harbintransport.backend.model.BusRushHourTraffic;
import com.harbintransport.backend.model.SankeyData;
import com.harbintransport.backend.model.BusStopFrequencyUsage;
import com.harbintransport.backend.model.DispatchSuggestion;
import com.harbintransport.backend.service.TrafficDataService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*") // 允许所有来源访问，实际项目中应限制特定前端域
public class TrafficDataController {

    private static final Logger logger = LoggerFactory.getLogger(TrafficDataController.class);

    @Autowired
    private TrafficDataService trafficDataService;

    @GetMapping("/health")
    public String healthCheck() {
        return "OK";
    }

    @GetMapping("/traffic/hourly_trends")
    public ResponseEntity<List<HourlyTrafficTrend>> getHourlyTrafficTrends() {
        try {
            List<HourlyTrafficTrend> trends = trafficDataService.getHourlyTrafficTrends();
            return ResponseEntity.ok(trends);
        } catch (DataProcessingException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    @GetMapping("/station/ranking")
    public ResponseEntity<List<StationPassengerRanking>> getStationRanking() {
        try {
            List<StationPassengerRanking> rankings = trafficDataService.getStationRanking();
            return ResponseEntity.ok(rankings);
        } catch (DataProcessingException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    @GetMapping("/route/funnel/{routeId}")
    public ResponseEntity<List<RouteStationFunnel>> getRouteFunnel(@PathVariable String routeId) {
        try {
            List<RouteStationFunnel> funnelData = trafficDataService.getRouteFunnel(routeId);
            return ResponseEntity.ok(funnelData);
        } catch (DataProcessingException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    @GetMapping("/subway/peak_crowd_ranking")
    public ResponseEntity<List<StationCrowdRanking>> getStationCrowdRanking() {
        try {
            List<StationCrowdRanking> rankings = trafficDataService.getStationCrowdRanking();
            return ResponseEntity.ok(rankings);
        } catch (DataProcessingException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    @GetMapping("/route/passenger_mobility")
    public ResponseEntity<List<RouteMobility>> getRouteMobility() {
        return ResponseEntity.ok(trafficDataService.getRouteMobility());
    }

    @GetMapping("/bus/rush_hour_traffic")
    public ResponseEntity<List<BusRushHourTraffic>> getBusRushHourTraffic() {
        try {
            List<BusRushHourTraffic> trafficData = trafficDataService.getBusRushHourTraffic();
            return ResponseEntity.ok(trafficData);
        } catch (Exception e) {
            logger.error("Error fetching bus rush hour traffic data", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @GetMapping("/traffic/od-analysis")
    public ResponseEntity<SankeyData> getODSankeyData() {
        try {
            SankeyData sankeyData = trafficDataService.getODSankeyData();
            return ResponseEntity.ok(sankeyData);
        } catch (Exception e) {
            logger.error("Error fetching OD Sankey data", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @GetMapping("/bus/stop-frequency-usage")
    public ResponseEntity<List<BusStopFrequencyUsage>> getBusStopFrequencyUsage() {
        return ResponseEntity.ok(trafficDataService.getBusStopFrequencyUsageData());
    }

    @GetMapping("/dispatch/suggestion_data")
    public ResponseEntity<List<DispatchSuggestion>> getDispatchSuggestionData(
            @RequestParam(required = false) String routeId,
            @RequestParam(required = false) String stationId,
            @RequestParam(required = false) Integer hour) {
        try {
            List<DispatchSuggestion> suggestionData = trafficDataService.getDispatchSuggestionData(routeId, stationId,
                    hour);
            return ResponseEntity.ok(suggestionData);
        } catch (Exception e) {
            logger.error("Error fetching dispatch suggestion data", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @GetMapping("/dispatch/routes")
    public ResponseEntity<List<String>> getDistinctRouteIds() {
        try {
            List<String> routeIds = trafficDataService.getDistinctRouteIds();
            return ResponseEntity.ok(routeIds);
        } catch (Exception e) {
            logger.error("Error fetching distinct route IDs", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @GetMapping("/dispatch/stations")
    public ResponseEntity<List<String>> getDistinctStationIdsByRouteId(@RequestParam String routeId) {
        try {
            List<String> stationIds = trafficDataService.getDistinctStationIdsByRouteId(routeId);
            return ResponseEntity.ok(stationIds);
        } catch (Exception e) {
            logger.error("Error fetching distinct station IDs for route " + routeId, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @ExceptionHandler(DataProcessingException.class)
    public ResponseEntity<String> handleDataProcessingException(DataProcessingException ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex.getMessage());
    }
}